﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Timers;
using System.Windows.Forms;
using EIS.ClientRoutineJob;
using EIS.ClientUtility;
using EIS.DatabaseHelper;
using EIS.Obj;
using EIS.ViewControl.Grid;
using EIS.ViewFactory;
using Janus.Windows.ExplorerBar;
using Timer = System.Timers.Timer;


namespace EIS.Main
{
    public partial class NavBarControl : UserControl
    {
        private UserControl CurrentView;

        public delegate void FormatNavBarDelegate(List<FormatNavBarParameter> paras);

        public FormatNavBarDelegate FormatNavBar;



        private Janus.Windows.UI.Dock.UIPanelManager panelManager;
        public NavBarControl(Janus.Windows.UI.Dock.UIPanelManager pm)
        {
            InitializeComponent();
            this.panelManager = pm;
            FormatNavBar = new FormatNavBarDelegate(FormatNavBarMethod);
            var timerFetchNavBarTextStyle = new TimerWithParentControl(this)
                                                                   {
                                                                       Interval =
                                                                           ClientConfig.Instance.
                                                                           RefreshNavBarTextAndStyle
                                                                   };

            timerFetchNavBarTextStyle.Elapsed += SetNavBarTextStyle;
            timerFetchNavBarTextStyle.Start();
            InitialNavBar();
        }

        private void navBar_ItemClick(object sender, Janus.Windows.ExplorerBar.ItemEventArgs e)
        {
            GlobalVariable.Instance.CurrentFunctionID = e.Item.Key;
            this.Cursor = Cursors.WaitCursor;
            try
            {



                if (CurrentView != null)
                {
                    ((MainWindow) panelManager.ContainerControl).Controls.Remove(CurrentView);
                    CurrentView.Dispose();
                    System.GC.Collect();
                }

                CurrentView = new EIS.ViewFactory.ViewFactory().GetView((String) (e.Item.Key));

                if (CurrentView == null)
                {
                    ((MainWindow) panelManager.ContainerControl).SetButtonStatus("DefineFunctionLayout", false);

                }
                else
                {
                    GlobalVariable.Instance.CurrentViewHandler = (UserControl) CurrentView;
                    ((MainWindow) panelManager.ContainerControl).SetItemView((UserControl) CurrentView);
                    ((MainWindow) panelManager.ContainerControl).SetButtonStatus("DefineFunctionLayout",
                                                                                 CurrentView.GetType().Name ==
                                                                                 "ViewGridDisplay");
                }
                this.Cursor = Cursors.Default;

            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Default;

                if ((ex.InnerException != null) && (ex.InnerException.GetType().Name == "SQLiteException"))
                {
                    ShowErrorMessageBox.Show("Please wait until the first synchonization with server finished, or press once the force refresh button. If this message continue appears, please contact your system administrator ");

                }
                else
                {
                    throw;
                }

            }

        }

        public void SetItemText(NavBarControl control)
        {
            FormatNavBarParameter para;
            var paras = new List<FormatNavBarParameter>();
            if (GlobalVariable.Instance.LogonResult.Layout.ApplicationLayoutFromServer == null) return;
            foreach (ApplicationLayoutFromServer func in GlobalVariable.Instance.LogonResult.Layout.ApplicationLayoutFromServer)
            {
                var dbHandler = new DBHandler();

                var count = dbHandler.UpdateRecordsReturnUnreadNumber(func.FunctionID, null);
                var displayText = func.DisplayName;
                
                if (count != 0)
                {
                    para = new FormatNavBarParameter(func.FunctionID, func.DisplayName + "(" + count + ")", true); 
                }else
                {
                    para = new FormatNavBarParameter(func.FunctionID, func.DisplayName , false); 
                }
                paras.Add(para);
               
            }
            while (!this.IsHandleCreated)
            {
                ;
            }
            BeginInvoke(control.FormatNavBar, paras);
        }

        private void SetNavBarTextStyle(Object source, ElapsedEventArgs e)
        {
            TimerWithParentControl timer = (TimerWithParentControl)source;
            timer.Enabled = false;
            SetItemText((NavBarControl)timer.Control);
            timer.Enabled = true;
        }

        public void FormatNavBarMethod(List<FormatNavBarParameter> paras)
        {
            foreach (var para in paras)
            {
                var found = false;
                foreach (ExplorerBarGroup group in this.navBar.Groups)
                {
                    foreach (ExplorerBarItem item in group.Items)
                    {
                        if ( item.Key == para.ItemKey)
                        {


                            item.Text = para.ItemText;
                            item.StateStyles.FormatStyle.FontBold = para.IsBold ? TriState.True : TriState.False;
                            found = true;
                            break;
                        }
                    }
                    if (found ) break;
                }
            }
        }


        public void InitialNavBar()
        {
            this.navBar.Groups.Clear();
            if (GlobalVariable.Instance.LogonResult == null) return;
            if (GlobalVariable.Instance.LogonResult.Layout.ApplicationLayoutFromServer == null) return;
            var funcItem = GlobalVariable.Instance.LogonResult.Layout.ApplicationLayoutFromServer;
            //First Step, Add Group To Nav Bar
            foreach (var layoutItem in funcItem)
            {
                if (!HasGroup(layoutItem.FunctionGroup))
                {
                    //Add Group To NavBar
                   ExplorerBarGroup groupToAdd = new ExplorerBarGroup();
                    groupToAdd.Key = layoutItem.FunctionGroup;
                    groupToAdd.Text = layoutItem.FunctionGroup;

                    this.navBar.Groups.Add(groupToAdd);
                }

            }

            //Second Step, Add Items. 

            foreach (var layoutItem in funcItem)
            {
                var hasitem = HasItem(layoutItem.FunctionGroup, layoutItem.FunctionID);
                if (!hasitem)
                {
                    var item = new ExplorerBarItem();
                    item.Text = layoutItem.DisplayName;
                    item.Key = layoutItem.FunctionID;
                    item.Cursor = Cursors.Hand;
                    navBar.Groups[layoutItem.FunctionGroup].Items.Add(item);

                }
            }


        }


        private bool HasGroup(string groupName)
        {
            return this.navBar.Groups.Cast<ExplorerBarGroup>().Any(@group => @group.Key == groupName);
        }
        private bool HasItem(string groupName, string itemKey)
        {
            //First, has the group?
            if (navBar.Groups.Cast<ExplorerBarGroup>().All(@group => @group.Key != groupName))
            {
                var groupToAdd = new ExplorerBarGroup();
                groupToAdd.Key = groupName;
                groupToAdd.Text = groupName;
                navBar.Groups.Add(groupToAdd);
            }

            //Second, Find the item in Group. 
            var navGroup = navBar.Groups[groupName];

            foreach (ExplorerBarItem item in navGroup.Items)
            {
                if (item.Key == itemKey) return true;
            }
            return false;
        }

        private void navBar_LayoutLoad(object sender, EventArgs e)
        {
            //Thrid Step: Set Unread No., etc.

            SetItemText(this);
        }
    }
}
